/**
 * Function.prototype.call 或  Function.prototype.apply 的作用一模一样，区别仅在于传入参数形式的不同。
 *
 * apply ：两个参数
 * 1：函数体内 this 指向，
 * 2：带下标的集合，可以为数组，可以为类数组。apply 方法把这个集合中的元素作为参数传递给被调用的函数
 */

var func = function (a, b, c) {
    console.log([a, b, c]);
};

func.apply(null, [1,2,3]);  //  [1, 2, 3]
// 参数1，2，3 被放在数组中一起传入 func 函数，它们分别对应 func 参数列表中的 a, b, c

/**
 * call ：参数数量不固定
 * 1：函数体内 this 指向，
 * 2：从第二个参数开始往后，每个参数被依次传入函数
 */
var func = function (a, b, c) {
    console.log([a, b, c]);
};

func.call(null, 1, 2, 3);  // [1, 2, 3]


// 当使用 call 或者 apply 的时候，如果传入的第一个参数为 null，函数体内的 this 会指向默认的宿主对象，在浏览器中则是 window

var func = function (a, b, c) {
    console.log(this === window);
};

func.apply(null, [1,2,3]);  // true

// 但如果是在严格模式下，函数体内的 this 还是为 null
var func = function (a, b, c) {
    'use strict'
    console.log(this === null);
};

func.apply(null, [1,2,3]);  // true

// 有时候使用 call 或者 apply 的目的不在于指定 this 指向，而是另有用途，比如借用其他对象的方法。
// 那么可以传入 null 来代替某个具体的对象

Math.max.apply(null, [1,2,3,4,5]); // 5